﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PDX;

namespace PdxDemo
{
    public class DemoValidationAdapter : DefaultValidationAdapter
    {
        class FluentEntry
        {
            public FluentEntry(FluentValidation.IValidator validator, object target)
            {
                this.Validator = validator;
                this.Target = target;

                Revalidate();
            }

            public FluentValidation.IValidator Validator { get; private set; }
            public object Target { get; private set; }
            public FluentValidation.Results.ValidationResult Result { get; private set; }

            public void Revalidate()
            {
                var result = Validator.Validate(Target);
                this.Result = result;
            }
        }

        Dictionary<FluentValidationDemo.IHaveValidator, FluentEntry> fluentEntries
            = new Dictionary<FluentValidationDemo.IHaveValidator, FluentEntry>();

        public DemoValidationAdapter(ViewmodelMetadata metadata)
            : base(metadata)
        {
        }

        protected override void notifier_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            foreach (var entry in fluentEntries.Values)
            {
                entry.Revalidate();
            }

            base.notifier_PropertyChanged(sender, e);
        }

        public override string GetMessage(IPropertyModel propModel)
        {
            var fluentValidated = propModel.Resolution.ResolvedDC as FluentValidationDemo.IHaveValidator;
            if (fluentValidated != null)
            {
                var entry = GetOrCreateFluentEntry(fluentValidated);
                foreach (var error in entry.Result.Errors)
                {
                    if (error.PropertyName == propModel.Resolution.Property.Name)
                    {
                        return error.ErrorMessage;
                    }
                }

                return string.Empty;
            }

            return base.GetMessage(propModel);
        }

        FluentEntry GetOrCreateFluentEntry(FluentValidationDemo.IHaveValidator target)
        {
            if (fluentEntries.ContainsKey(target))
            {
                return fluentEntries[target];
            }
            else
            {
                var validator = target.GetValidator();
                var entry = new FluentEntry(validator, target);
                fluentEntries[target] = entry;
                return entry;
            }
        }
    }
}
